﻿/// <reference path="_namespace.js" />
/// <reference path="../components/MenuItemDisplayFlags.js" />

/*****************************************************************************
Ajax library class definition. Kevin Robinson 2007.
Class: ajax.windows.FrmSimpleAdmin
/*****************************************************************************/

ajax.lang.addNamespace("ajax.windows");
ajax.lang.imports("ajax.components.MenuItemDisplayFlags");

// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin = function(doc, layerName, w, h, displayFlags, sText, parentNode, bModal, taskBar)
{    
    ajax.windows.FrmSimpleAdmin.superConstructor.call(this, doc, layerName, w, h, displayFlags, sText, parentNode, bModal, taskBar);
    
    // Clients should set these
    this.dataTable              = null;                              // An instance of ajax.data.DataTable
    this.editFormClassName      = "ajax.windows.FrmSimpleAdminEdit"; // The class of the edit form to use
    this.dataGridClassName      = "ajax.components.DataGrid";        // the class of DataGrid to use.
    this.ignoreGridColumns      = [];                                // The grid columns we will not show.
    
    this.set_isTemplateControl(true);
        
    this.dialogSaving           = false;    // Set to true only while we wait for response from server from dialog save.   
    this._grid                  = null;     // DataGrid
    this._editForm              = null;     // Form used for editing
    this._toolsMenuItem         = null;     // Tools Menu Item
    this._toolsMenu             = null;     // Tools Menu
    // Handles to menu items
    this._toolsMenuNewItem      = null;
    this._toolsMenuEditItem     = null;
    this._toolsMenuDeleteItem   = null;  
    
    // Freeze dry the handlers we will attach to the dataTable (so we can remove them as we wish)
    this.dataTableErrorDelegate     = null;
    this.dataTableUpdateDelegate    = null;
    this.daatTableDataEventDelegate = null;
    this.onDataEventHandler         = this.onDataEvent.bind(this);
    this.onDataUpdatedHandler       = this.onDataUpdated.bind(this);
    this.onDataErrorHandler         = this.onDataError.bind(this);
    
    this.onGridRowBoundHandler      = this.onGridRowBound.bind(this);
    this.onGridDblClickHandler      = this.onGridDblClick.bind(this);
}

// --------------------------------------------------------------------
ajax.lang.extend("ajax.windows.FrmSimpleAdmin", "ajax.windows.WinForm");
// --------------------------------------------------------------------

// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.load = function()
{// Override load
    // Call Base
    ajax.windows.FrmSimpleAdmin.superClass.load.call(this);
    
    // We will reuse these.
    this.dataTableErrorDelegate     = this.dataTable.getEvent(this.dataTable.window, "onHttpError");
    this.dataTableUpdateDelegate    = this.dataTable.getEvent(this.dataTable.window, "onUpdated");
    this.dataTableDataEventDelegate = this.dataTable.getEvent(this.dataTable.window, "onDataEvent");
    
    this._createMenuBar();
    this._createGrid();   
    
}

// Public virtual methods
// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.getEditForm = function()
{// Override to customise this
    if (this._editForm == null)
    {        
        var flags = ajax.windows.WinFormDisplayFlags;
        this._editForm = ajax.lang.safeNew(this.editFormClassName, this.doc, 400, 250, this.content);
        this._editForm.getEvent(this.window, "onSave").addListener(this.onDialogSave.bind(this));
        this.addMdiChild(this._editForm);
        this._editForm.showMaximised();        
    }
    return this._editForm;
}
// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.onDataEvent = function(e, router)
{
    this._grid.progressIndicator.showCentered();    
}
// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.onDataUpdated = function(e, router)
{    
    // Respond to data updates here.    
    if (this._editForm) // small optimization - check it exists first.
        this.getEditForm().hide();        
    this.dialogSaving = false; // Save is complete.     
    
    // Get the grid to handle the update
    this._grid.onDataTableUpdateHandler(e, router);
    this._grid.progressIndicator.hide();  // Hide the progress indicator. 
}

// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.onDataError = function(res)
{                
    if (this.dialogSaving)    
        this.getEditForm().show();  // Show in it's former state.
    this.dialogSaving = false;      // Reset 
    this._grid.progressIndicator.hide(); // Hide the progress indicator.
}

// --------------------------------------------------------------------
// Handle Menu Events
ajax.windows.FrmSimpleAdmin.prototype.onMenuNew = function()
{
    // Show Edit Window with new data row
    this.getEditForm().dataSource = this.dataTable.newRow();
    this.getEditForm().show();
    this.getEditForm().dataBind();
}
// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.onMenuEdit = function()
{
    // Show Edit window with selected row's data    
    this.getEditForm().dataSource = this._grid.selectedRow.dataRow;
    this.getEditForm().show();
    this.getEditForm().dataBind();
}
// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.onMenuDelete = function()
{       
    // Send selected row data to delete method of data table
    this.dataTable.deleteData(this._grid.selectedRow.dataRow, null); // DO NOT specify sole error handler
}
// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.onDialogSave = function(e, router)
{   
    var dialog = router.sender;    
    this.dataTable.saveData(e, null); // send the dialog datasource (1 row) to be saved by the dataTable.
    this.dialogSaving      = true; // remember that we are waiting for the server from the dialog
}
// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.onGridRowBound = function(e, router)
{
    // Add a context handler to the row
    var onContext = ajax.lang.getEvent(this.window, e.tableRow, "oncontextmenu");
    onContext.returnFalse = true;
    onContext.addListener(this.onGridRowContext.bind(this));
}
// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.onGridContext = function(e, router)
{
    // User context clicked on the grid (but not a row)
    this._grid.unSelectRows();
    var toolsMenu = this.getToolsMenu();
    toolsMenu.layerOffsetX = toolsMenu.layerOffsetY = -20; // Popup mode
    toolsMenu.showEvent(e);
}
// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.onGridRowContext = function(e, router)
{
    // User context clicked on a grid row
    this._grid.unSelectRows();
    this._grid.selectRow(router.sender);
    var toolsMenu = this.getToolsMenu();
    toolsMenu.layerOffsetX = toolsMenu.layerOffsetY = -20; // Popup mode
    toolsMenu.showEvent(e);
}
// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.onGridDblClick = function(e, router)
{
    // as per edit
    this.onMenuEdit();
}



// Public methods (probably don't need to be overridden)
// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.getToolsMenu = function()
{
    if (this._toolsMenu == null)    
        this.createToolsMenu();        
    
        
    // Only allow edit and delete if there is a row selected
    this._toolsMenuEditItem.setEnabled(this._grid.selectedRow != null);
    this._toolsMenuDeleteItem.setEnabled(this._grid.selectedRow != null);
    
    return this._toolsMenu;
}

// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.createToolsMenu = function()
{
    // Create tools Menu with autohide
    this._toolsMenu = ajax.lang.safeNew("ajax.components.Menu", this.doc, "", 200, 96, this.layer);
    ajax.lang.getEvent(this.window, this.doc, "onmouseup").addListener(this._toolsMenu.hide.bind(this._toolsMenu)); 

    // Create New
    this._toolsMenuNewItem = ajax.lang.safeNew("ajax.components.MenuItem", this.doc, "Add New Record...", ajax.getDomainPath() + "/images/new16.gif");
    this._toolsMenuNewItem.getEvent(this.window, "onSelected").addListener(this.onMenuNew.bind(this));
    this._toolsMenu.addMenuItem(this._toolsMenuNewItem);

    // Create Edit
    this._toolsMenuEditItem = ajax.lang.safeNew("ajax.components.MenuItem", this.doc, "Edit Selected Record...", ajax.getDomainPath() + "/images/edit16.gif");
    this._toolsMenuEditItem.getEvent(this.window, "onSelected").addListener(this.onMenuEdit.bind(this));
    this._toolsMenu.addMenuItem(this._toolsMenuEditItem);

    // Spacer
    this._toolsMenu.addMenuItem(ajax.lang.safeNew("ajax.components.MenuItem", this.doc, "-"));

    // Create Delete
    this._toolsMenuDeleteItem = ajax.lang.safeNew("ajax.components.MenuItem", this.doc, "Delete Selected Record...", ajax.getDomainPath() + "/images/red_cross.gif");
    this._toolsMenuDeleteItem.getEvent(this.window, "onSelected").addListener(function(e)
        {
            if (confirm("Are you sure you want to delete this record?"))
                this.onMenuDelete.call(this);
        }.bind(this)
    ); 
    this._toolsMenu.addMenuItem(this._toolsMenuDeleteItem);
}

// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.showToolsMenu = function()
{    
    var toolsMenu = this.getToolsMenu();    
    
    toolsMenu.layerOffsetX = toolsMenu.layerOffsetY = 0;    // Reset offset for non popup rendering          
    toolsMenu.showBelow(this._toolsMenuItem.element);
}


// Private methods
// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype._createMenuBar = function()
{
    // Add the top level menu items top the menu bar
    var flags = ajax.components.MenuItemDisplayFlags;
    this._toolsMenuItem = ajax.lang.safeNew("ajax.components.MenuItem", this.doc, "Tools", ajax.getDomainPath() + "/images/tools16.gif", "", null, flags.Text | flags.Image);
    this._toolsMenuItem.getEvent(this.window, "onSelected").addListener(this.showToolsMenu.bind(this));
    this.getMenuBar().addMenuItem(this._toolsMenuItem, 70);    
}
// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype._createGrid = function()
{
    // Create at 50, 50 and resize it later...
    this._grid = ajax.lang.safeNew(this.dataGridClassName, this.doc, this.content, "", 50, 50, true);
    this._grid.active = true;
    this._grid.ignoreColumns = this.ignoreGridColumns;
    this._grid.show();
    
    // Subscribe to the context menu of the grid's layer
    var gridContext = ajax.lang.getEvent(this.window, this._grid.layer, "oncontextmenu");
    gridContext.returnFalse = true;
    gridContext.addListener(this.onGridContext.bind(this));
    
    // Subscribe to our resize event and set the grid size accordingly
    this.getEvent(this.window, "onResize").addListener(function(e)
        {
            var contentSize = this.getContentRect();
            contentSize.height -= 60; // HACK, allowing for label!
            this._grid.setSize(contentSize.width, contentSize.height);
            
        }
    );
    
    // Force resize to get everything sized up OK
    this.onResize.call(this, this.getRect());
    
    // Subscribe to Grid Data events
    this._grid.getEvent(this.window, "onDataBoundRow").addListener(this.onGridRowBoundHandler);
    this._grid.getEvent(this.window, "onRowDblClick").addListener(this.onGridDblClickHandler);
    
    // DANGER with this - originally this was the way but now the grid handler is called from our own
    // freeze dried delegates.
    //this.dataTable.getEvent(this.dataTable.window, "onUpdated").addListener(this._grid.onDataTableUpdateHandler.bind(this._grid));
        
    // Add our own listener to data updates so we can respond. 
    // DANGER we are adding a reference to ourselves to the dataTable. We need to think about removing these 
    // listeners when we are shut down or we will cause a memory leak.
    this.dataTableUpdateDelegate.addListener(this.onDataUpdatedHandler);  
    this.dataTableErrorDelegate.addListener(this.onDataErrorHandler);
    this.dataTableDataEventDelegate.addListener(this.onDataEventHandler);
    
    
    // Finally, make the call, imatating a call from the DataTable (pretend to be router).
    this.onDataUpdated(null, {sender: this.dataTable});    
    //this._grid.onDataTableUpdateHandler(null, {sender: this.dataTable});        
}

// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.dispose = function()
{
    // Remove the DANGER - remove our event listeners from the dataTable.
    this.dataTableUpdateDelegate.removeListener(this.onDataUpdatedHandler);
    this.dataTableErrorDelegate.removeListener(this.onDataErrorHandler);
    this.dataTableDataEventDelegate.removeListener(this.onDataEventHandler);
    
    // Call base
    ajax.windows.FrmSimpleAdmin.superClass.dispose.call(this);
}

// --------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.prototype.toString = function()
{
    return "ajax.windows.FrmSimpleAdmin";
}

//-----------------------------------------------------------------------------
ajax.windows.FrmSimpleAdmin.cast = function(obj)
{///<returns type="ajax.windows.FrmSimpleAdmin"/>
    return obj;
}